package sg.nus.iss.vmcs.controllers;

import java.util.Arrays;

import sg.nus.iss.vmcs.gui.GUIChangeManager;
import sg.nus.iss.vmcs.gui.GUIChangeManagerEvent;
import sg.nus.iss.vmcs.models.StoreItem;
import sg.nus.iss.vmcs.utils.MoneyFormatter;
import sg.nus.iss.vmcs.utils.StoreType;

/**
 * Change Giver Controller managing the Change to be given
 * @author Philip Chew
 */
public class ChangeGiver {
	
	/** Transaction Controller that manages this class */
	private TransactionController transCtrl;
	
	/**
	 * Creates an instance of the change controller
	 * @param transCtrl Reference to the transaction controller
	 */
	public ChangeGiver(TransactionController transCtrl) {
		this.transCtrl = transCtrl;
	}
	
	/**
	 * Resets the Refund / Change tray on the customer panel
	 */
	public void resetChange() {
		GUIChangeManager.getInstance().fireEvent(GUIChangeManagerEvent.SetChange);
	}
	
	/**
	 * Manages the operation of giving change to the customer
	 * @param changeRqd The amount of change required
	 * @return True if change giving is successful, false if otherwise
	 */
	public boolean giveChange(int changeRqd) {
		//Can't give negative change or 0
		if(changeRqd <= 0) return true;
		
		int changeGiven = 0;
		StoreItem[] cashStoreItems = transCtrl.getMainController().getStoreController().getStore(StoreType.CASH).getItems();
		Arrays.sort(cashStoreItems, StoreItem.getSIDscComparator());
		
		for(int i = 0; i < cashStoreItems.length; i++) {
			int cashStoreItemValue = cashStoreItems[i].getContent().getValue();
			
			while(cashStoreItemValue <= (changeRqd - changeGiven)) {
				if(cashStoreItems[i].unstore()) {
					changeGiven += cashStoreItemValue;
				}
				else {
					break;
				}
			}
		}
		
		GUIChangeManager.getInstance().fireEvent(GUIChangeManagerEvent.SetChange, MoneyFormatter.toMoney(changeGiven));
		return changeGiven == changeRqd;
	}
	
	/**
	 * This is used to display the appropriate message on the no change available display, depending on
	 * current change availability
	 */
	public void displayChangeStatus() {
		StoreItem[] coinItems = transCtrl.getMainController().getStoreController().getStore(StoreType.CASH).getItems();
		
		boolean changeAvailable = false;
		
		for(StoreItem ci : coinItems) {
			if(ci.getQuantity() > 0) {
				changeAvailable = true;
			} 
		}
		
		GUIChangeManager.getInstance().fireEvent(GUIChangeManagerEvent.SetChangeStatus, changeAvailable);
	}
}
